home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / cc-mode / cc-align.el.z / cc-align.el
Encoding:
Text File  |  1998-05-21  |  15.9 KB  |  485 lines

  1. ;;; cc-align.el --- custom indentation functions for CC Mode
  2.  
  3. ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
  4.  
  5. ;; Authors:    1992-1997 Barry A. Warsaw
  6. ;;             1987 Dave Detlefs and Stewart Clamen
  7. ;;             1985 Richard M. Stallman
  8. ;; Maintainer: cc-mode-help@python.org
  9. ;; Created:    22-Apr-1997 (split from cc-mode.el)
  10. ;; Version:    See cc-mode.el
  11. ;; Keywords:   c languages oop
  12.  
  13. ;; This file is part of GNU Emacs.
  14.  
  15. ;; GNU Emacs is free software; you can redistribute it and/or modify
  16. ;; it under the terms of the GNU General Public License as published by
  17. ;; the Free Software Foundation; either version 2, or (at your option)
  18. ;; any later version.
  19.  
  20. ;; GNU Emacs is distributed in the hope that it will be useful,
  21. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. ;; GNU General Public License for more details.
  24.  
  25. ;; You should have received a copy of the GNU General Public License
  26. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  27. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  28. ;; Boston, MA 02111-1307, USA.
  29.  
  30. (eval-when-compile
  31.   (require 'cc-defs)
  32.   (require 'cc-vars)
  33.   (require 'cc-engine)
  34.   (require 'cc-langs))
  35.  
  36.  
  37. ;; Standard indentation line-ups
  38. (defun c-lineup-arglist (langelem)
  39.   ;; lineup the current arglist line with the arglist appearing just
  40.   ;; after the containing paren which starts the arglist.
  41.   (save-excursion
  42.     (let* ((containing-sexp
  43.         (save-excursion
  44.           ;; arglist-cont-nonempty gives relpos ==
  45.           ;; to boi of containing-sexp paren. This
  46.           ;; is good when offset is +, but bad
  47.           ;; when it is c-lineup-arglist, so we
  48.           ;; have to special case a kludge here.
  49.           (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
  50.           (progn
  51.             (beginning-of-line)
  52.             (backward-up-list 1)
  53.             (skip-chars-forward " \t" (c-point 'eol)))
  54.         (goto-char (cdr langelem)))
  55.           (point)))
  56.        (langelem-col (c-langelem-col langelem t)))
  57.       (if (save-excursion
  58.         (beginning-of-line)
  59.         (looking-at "[ \t]*)"))
  60.       (progn (goto-char (match-end 0))
  61.          (forward-sexp -1)
  62.          (forward-char 1)
  63.          (c-forward-syntactic-ws)
  64.          (- (current-column) langelem-col))
  65.     (goto-char containing-sexp)
  66.     (or (eolp)
  67.         (not (memq (char-after) '(?{ ?\( )))
  68.         (let ((eol (c-point 'eol))
  69.           (here (progn
  70.               (forward-char 1)
  71.               (skip-chars-forward " \t")
  72.               (point))))
  73.           (c-forward-syntactic-ws)
  74.           (if (< (point) eol)
  75.           (goto-char here))))
  76.     (- (current-column) langelem-col)
  77.     ))))
  78.  
  79. (defun c-lineup-arglist-intro-after-paren (langelem)
  80.   ;; lineup an arglist-intro line to just after the open paren
  81.   (save-excursion
  82.     (let ((langelem-col (c-langelem-col langelem t))
  83.       (ce-curcol (save-excursion
  84.                (beginning-of-line)
  85.                (backward-up-list 1)
  86.                (skip-chars-forward " \t" (c-point 'eol))
  87.                (current-column))))
  88.       (- ce-curcol langelem-col -1))))
  89.  
  90. (defun c-lineup-arglist-close-under-paren (langelem)
  91.   ;; lineup an arglist-close line under the corresponding open paren
  92.   (save-excursion
  93.     (let ((langelem-col (c-langelem-col langelem t))
  94.       (ce-curcol (save-excursion
  95.                (beginning-of-line)
  96.                (backward-up-list 1)
  97.                (current-column))))
  98.       (- ce-curcol langelem-col))))
  99.  
  100. (defun c-lineup-close-paren (langelem)
  101.   ;; Indents the closing paren under its corresponding open paren if
  102.   ;; the open paren is followed by code.  If the open paren ends its
  103.   ;; line, no indentation is added.  E.g:
  104.   ;;
  105.   ;; main (int,                main (
  106.   ;;       char **               int, char **
  107.   ;;      )            <->     )              <- c-lineup-close-paren
  108.   ;;
  109.   ;; Works with any type of paren.
  110.   (save-excursion
  111.     (condition-case nil
  112.     (let (opencol spec)
  113.       (beginning-of-line)
  114.       (backward-up-list 1)
  115.       (setq spec (if (fboundp 'c-looking-at-special-brace-list)
  116.              (c-looking-at-special-brace-list)))
  117.       (if spec (goto-char (car spec)))
  118.       (setq opencol (current-column))
  119.       (forward-char 1)
  120.       (if spec (progn
  121.              (c-forward-syntactic-ws)
  122.              (forward-char 1)))
  123.       (c-forward-syntactic-ws (c-point 'eol))
  124.       (if (eolp)
  125.           0
  126.         (- opencol (c-langelem-col langelem t))))
  127.       (error 0))))
  128.  
  129. (defun c-lineup-streamop (langelem)
  130.   ;; lineup stream operators
  131.   (save-excursion
  132.     (let ((langelem-col (c-langelem-col langelem)))
  133.       (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
  134.       (goto-char (match-beginning 0))
  135.       (- (current-column) langelem-col))))
  136.  
  137. (defun c-lineup-multi-inher (langelem)
  138.   ;; line up multiple inheritance lines
  139.   (save-excursion
  140.     (let ((eol (c-point 'eol))
  141.       (here (point))
  142.       (langelem-col (c-langelem-col langelem)))
  143.       (skip-chars-forward "^:" eol)
  144.       (skip-chars-forward " \t:" eol)
  145.       (if (or (eolp)
  146.           (looking-at c-comment-start-regexp))
  147.       (c-forward-syntactic-ws here))
  148.       (- (current-column) langelem-col)
  149.       )))
  150.  
  151. (defun c-lineup-java-inher (langelem)
  152.   ;; line up Java implements and extends continuations
  153.   (save-excursion
  154.     (let ((langelem-col (c-langelem-col langelem)))
  155.       (forward-word 1)
  156.       (if (looking-at "[ \t]*$")
  157.       langelem-col
  158.     (c-forward-syntactic-ws)
  159.     (- (current-column) langelem-col)))))
  160.  
  161. (defun c-lineup-java-throws (langelem)
  162.   ;; lineup func-decl-cont's in Java which are continuations of throws
  163.   ;; declarations.  If `throws' starts the previous line, line up to
  164.   ;; just after that keyword.  If not, lineup under the previous line.
  165.   (save-excursion
  166.     (let ((iopl (c-point 'iopl))
  167.       (langelem-col (c-langelem-col langelem t))
  168.       (extra 0))
  169.       (back-to-indentation)
  170.       (cond
  171.        ((looking-at "throws[ \t\n]")
  172.     (goto-char (cdr langelem))
  173.     (setq extra c-basic-offset))
  174.        ((and (goto-char iopl)
  175.          (looking-at "throws[ \t\n]"))
  176.     (forward-word 1)
  177.     (skip-chars-forward " \t")
  178.     (if (eolp)
  179.         (progn
  180.           (back-to-indentation)
  181.           (setq extra c-basic-offset))))
  182.        (t (goto-char iopl)))
  183.       (+ (- (current-column) langelem-col) extra))))
  184.  
  185. (defun c-indent-one-line-block (langelem)
  186.   ;; Adds c-basic-offset to the indentation if the line is a one line
  187.   ;; block, otherwise 0.  E.g:
  188.   ;;
  189.   ;; if (n)                     if (n)
  190.   ;;   {m+=n; n=0;}     <->     {            <- c-indent-one-line-block
  191.   ;;                              m+=n; n=0;
  192.   ;;                            }
  193.   (save-excursion
  194.     (let ((eol (progn (end-of-line) (point))))
  195.       (beginning-of-line)
  196.       (skip-chars-forward " \t")
  197.       (if (and (eq (following-char) ?{)
  198.            (condition-case nil
  199.            (progn (forward-sexp) t)
  200.          (error nil))
  201.            (<= (point) eol)
  202.            (eq (preceding-char) ?}))
  203.       c-basic-offset
  204.     0))))
  205.  
  206. (defun c-lineup-C-comments (langelem)
  207.   ;; line up C block comment continuation lines
  208.   (save-excursion
  209.     (let ((here (point))
  210.       (stars (progn (back-to-indentation)
  211.             (skip-chars-forward "*")))
  212.       (langelem-col (c-langelem-col langelem)))
  213.       (back-to-indentation)
  214.       (if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t))
  215.       (progn
  216.         (if (not (looking-at "[*]+"))
  217.         (progn
  218.           ;; we now have to figure out where this comment begins.
  219.           (goto-char here)
  220.           (back-to-indentation)
  221.           (if (looking-at "[*]+/")
  222.               (progn (goto-char (match-end 0))
  223.                  (forward-comment -1))
  224.             (goto-char (cdr langelem))
  225.             (back-to-indentation))))
  226.         (- (current-column) langelem-col))
  227.     (if (zerop stars)
  228.         (progn
  229.           (skip-chars-forward " \t")
  230.           (- (current-column) langelem-col))
  231.       ;; how many stars on comment opening line?  if greater than
  232.       ;; on current line, align left.  if less than or equal,
  233.       ;; align right.  this should also pick up Javadoc style
  234.       ;; comments.
  235.       (if (> (length (match-string 1)) stars)
  236.           (progn
  237.         (back-to-indentation)
  238.         (- (current-column) -1 langelem-col))
  239.         (- (current-column) stars langelem-col))
  240.       )))))
  241.  
  242. (defun c-lineup-comment (langelem)
  243.   ;; support old behavior for comment indentation. we look at
  244.   ;; c-comment-only-line-offset to decide how to indent comment
  245.   ;; only-lines
  246.   (save-excursion
  247.     (back-to-indentation)
  248.     ;; this highly kludgiforous flag prevents the mapcar over
  249.     ;; c-syntactic-context from entering an infinite loop
  250.     (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag)))
  251.       (cond
  252.        ;; CASE 1: preserve comment-column
  253.        (recurse-prevention-flag 0)
  254.        ((= (current-column) comment-column)
  255.     ;; we have to subtract out all other indentation
  256.     (- comment-column (apply '+ (mapcar 'c-get-offset
  257.                         c-syntactic-context))))
  258.        ;; indent as specified by c-comment-only-line-offset
  259.        ((not (bolp))
  260.     (or (car-safe c-comment-only-line-offset)
  261.         c-comment-only-line-offset))
  262.        (t
  263.     (or (cdr-safe c-comment-only-line-offset)
  264.         (car-safe c-comment-only-line-offset)
  265.         -1000))            ;jam it against the left side
  266.        ))))
  267.  
  268. (defun c-lineup-runin-statements (langelem)
  269.   ;; line up statements in coding standards which place the first
  270.   ;; statement on the same line as the block opening brace.
  271.   (if (eq (char-after (cdr langelem)) ?{)
  272.       (save-excursion
  273.     (let ((langelem-col (c-langelem-col langelem)))
  274.       (forward-char 1)
  275.       (skip-chars-forward " \t")
  276.       (- (current-column) langelem-col)))
  277.     0))
  278.  
  279. (defun c-lineup-math (langelem)
  280.   ;; line up math statement-cont after the equals
  281.   (save-excursion
  282.     (let ((equalp (save-excursion
  283.             (goto-char (c-point 'boi))
  284.             (skip-chars-forward "^=" (c-point 'eol))
  285.             (and (eq (char-after) ?=)
  286.              (- (point) (c-point 'boi)))))
  287.       (langelem-col (c-langelem-col langelem))
  288.       donep)
  289.       (while (and (not donep)
  290.           (< (point) (c-point 'eol)))
  291.     (skip-chars-forward "^=" (c-point 'eol))
  292.     (if (c-in-literal (cdr langelem))
  293.         (forward-char 1)
  294.       (setq donep t)))
  295.       (if (not (eq (char-after) ?=))
  296.       ;; there's no equal sign on the line
  297.       c-basic-offset
  298.     ;; calculate indentation column after equals and ws, unless
  299.     ;; our line contains an equals sign
  300.     (if (not equalp)
  301.         (progn
  302.           (forward-char 1)
  303.           (skip-chars-forward " \t")
  304.           (setq equalp 0)))
  305.     (- (current-column) equalp langelem-col))
  306.       )))
  307.  
  308. (defun c-lineup-ObjC-method-call (langelem)
  309.   ;; Line up methods args as elisp-mode does with function args: go to
  310.   ;; the position right after the message receiver, and if you are at
  311.   ;; (eolp) indent the current line by a constant offset from the
  312.   ;; opening bracket; otherwise we are looking at the first character
  313.   ;; of the first method call argument, so lineup the current line
  314.   ;; with it.
  315.   (save-excursion
  316.     (let* ((extra (save-excursion
  317.             (back-to-indentation)
  318.             (c-backward-syntactic-ws (cdr langelem))
  319.             (if (eq (char-before) ?:)
  320.             (- c-basic-offset)
  321.               0)))
  322.        (open-bracket-pos (cdr langelem))
  323.            (open-bracket-col (progn
  324.                    (goto-char open-bracket-pos)
  325.                    (current-column)))
  326.            (target-col (progn
  327.              (forward-char)
  328.              (forward-sexp)
  329.              (skip-chars-forward " \t")
  330.              (if (eolp)
  331.                  (+ open-bracket-col c-basic-offset)
  332.                (current-column))))
  333.        )
  334.       (- target-col open-bracket-col extra))))
  335.  
  336. (defun c-lineup-ObjC-method-args (langelem)
  337.   ;; Line up the colons that separate args. This is done trying to
  338.   ;; align colons vertically.
  339.   (save-excursion
  340.     (let* ((here (c-point 'boi))
  341.        (curcol (progn (goto-char here) (current-column)))
  342.        (eol (c-point 'eol))
  343.        (relpos (cdr langelem))
  344.        (first-col-column (progn
  345.                    (goto-char relpos)
  346.                    (skip-chars-forward "^:" eol)
  347.                    (and (eq (char-after) ?:)
  348.                     (current-column)))))
  349.       (if (not first-col-column)
  350.       c-basic-offset
  351.     (goto-char here)
  352.     (skip-chars-forward "^:" eol)
  353.     (if (eq (char-after) ?:)
  354.         (+ curcol (- first-col-column (current-column)))
  355.       c-basic-offset)))))
  356.  
  357. (defun c-lineup-ObjC-method-args-2 (langelem)
  358.   ;; Line up the colons that separate args. This is done trying to
  359.   ;; align the colon on the current line with the previous one.
  360.   (save-excursion
  361.     (let* ((here (c-point 'boi))
  362.        (curcol (progn (goto-char here) (current-column)))
  363.        (eol (c-point 'eol))
  364.        (relpos (cdr langelem))
  365.        (prev-col-column (progn
  366.                   (skip-chars-backward "^:" relpos)
  367.                   (and (eq (char-before) ?:)
  368.                    (- (current-column) 1)))))
  369.       (if (not prev-col-column)
  370.       c-basic-offset
  371.     (goto-char here)
  372.     (skip-chars-forward "^:" eol)
  373.     (if (eq (char-after) ?:)
  374.         (+ curcol (- prev-col-column (current-column)))
  375.       c-basic-offset)))))
  376.  
  377. (defun c-lineup-dont-change (langelem)
  378.   ;; Do not change the indentation of the current line
  379.   (save-excursion
  380.     (back-to-indentation)
  381.     (current-column)))
  382.  
  383.  
  384.  
  385. (defun c-snug-do-while (syntax pos)
  386.   "Dynamically calculate brace hanginess for do-while statements.
  387. Using this function, `while' clauses that end a `do-while' block will
  388. remain on the same line as the brace that closes that block.
  389.  
  390. See `c-hanging-braces-alist' for how to utilize this function as an
  391. ACTION associated with `block-close' syntax."
  392.   (save-excursion
  393.     (let (langelem)
  394.       (if (and (eq syntax 'block-close)
  395.            (setq langelem (assq 'block-close c-syntactic-context))
  396.            (progn (goto-char (cdr langelem))
  397.               (if (eq (char-after) ?{)
  398.               (c-safe (forward-sexp -1)))
  399.               (looking-at "\\<do\\>[^_]")))
  400.       '(before)
  401.     '(before after)))))
  402.  
  403. (defun c-gnu-impose-minimum ()
  404.   "Imposes a minimum indentation for lines inside a top-level construct.
  405. The variable `c-label-minimum-indentation' specifies the minimum
  406. indentation amount."
  407.   (let ((non-top-levels '(defun-block-intro statement statement-cont
  408.                statement-block-intro statement-case-intro
  409.                statement-case-open substatement substatement-open
  410.                case-label label do-while-closure else-clause
  411.                ))
  412.     (syntax c-syntactic-context)
  413.     langelem)
  414.     (while syntax
  415.       (setq langelem (car (car syntax))
  416.         syntax (cdr syntax))
  417.       ;; don't adjust comment-only lines
  418.       (cond ((eq langelem 'comment-intro)
  419.          (setq syntax nil))
  420.         ((memq langelem non-top-levels)
  421.          (save-excursion
  422.            (setq syntax nil)
  423.            (back-to-indentation)
  424.            (if (zerop (current-column))
  425.            (insert (make-string c-label-minimum-indentation 32)))
  426.            ))
  427.         ))))
  428.  
  429.  
  430. ;; Useful for c-hanging-semi&comma-criteria
  431. (defun c-semi&comma-inside-parenlist ()
  432.   "Controls newline insertion after semicolons in parenthesis lists.
  433. If a comma was inserted, no determination is made.  If a semicolon was
  434. inserted inside a parenthesis list, no newline is added otherwise a
  435. newline is added.  In either case, checking is stopped.  This supports
  436. exactly the old newline insertion behavior."
  437.   ;; newline only after semicolon, but only if that semicolon is not
  438.   ;; inside a parenthesis list (e.g. a for loop statement)
  439.   (if (not (eq last-command-char ?\;))
  440.       nil                ; continue checking
  441.     (if (condition-case nil
  442.         (save-excursion
  443.           (up-list -1)
  444.           (not (eq (char-after) ?\()))
  445.       (error t))
  446.     t
  447.       'stop)))
  448.  
  449. ;; Suppresses newlines before non-blank lines
  450. (defun c-semi&comma-no-newlines-before-nonblanks ()
  451.   "Controls newline insertion after semicolons.
  452. If a comma was inserted, no determination is made.  If a semicolon was
  453. inserted, and the following line is not blank, no newline is inserted.
  454. Otherwise, no determination is made."
  455.   (save-excursion
  456.     (if (and (= last-command-char ?\;)
  457.          ;;(/= (point-max)
  458.          ;;    (save-excursion (skip-syntax-forward " ") (point))
  459.          (zerop (forward-line 1))
  460.          (not (looking-at "^[ \t]*$")))
  461.     'stop
  462.       nil)))
  463.  
  464. ;; Suppresses new lines after semicolons in one-liners methods
  465. (defun c-semi&comma-no-newlines-for-oneline-inliners ()
  466.   "Controls newline insertion after semicolons for some one-line methods.
  467. If a comma was inserted, no determination is made.  Newlines are
  468. suppressed in one-liners, if the line is an in-class inline function.
  469. For other semicolon contexts, no determination is made."
  470.   (let ((syntax (c-guess-basic-syntax))
  471.         (bol (save-excursion
  472.                (if (c-safe (up-list -1) t)
  473.                    (c-point 'bol)
  474.                  -1))))
  475.     (if (and (eq last-command-char ?\;)
  476.              (eq (car (car syntax)) 'inclass)
  477.              (eq (car (car (cdr syntax))) 'topmost-intro)
  478.              (= (c-point 'bol) bol))
  479.         'stop
  480.       nil)))
  481.  
  482.  
  483. (provide 'cc-align)
  484. ;;; cc-align.el ends here
  485.